polyfill 和 runtime 区别
Babel 只是转换 syntax 层语法, 所以需要 @babel/polyfill 来处理 API 兼容,
又因为 polyfill 体积太大,所以通过 preset 的 useBuiltIns 来实现按需加载,
再接着为了满足 npm 库开发的需要 出现了 @babel/runtime 来做隔离。
Syntax:像 箭头函数、let、const 等等这些,我们在运行时无法重写的,简单记忆为 新的关键字或者符号。
API: 指那些我们可以通过函数重新覆盖的语法,如新的内置函数(如 Promise 或 WeakMap )、静态方法(如 Array.from 或 Object.assign )、实例方法(如 Array.prototype.includes )等等。
Babel 默认只负责转换 Syntax , 而 API 层面的单独放在了 polyfill 这个模块处理,
1. 1. @babel/preset-env 零配置转换

2. 2. 全量 polyfill
@babel/polyfill 和 Babel 版本不同,使用的方式也不太一样,具体参考文档: 链接

问题
- 把对应浏览器不支持的语法全部重新写一遍,简单粗暴的解决兼容性问题, 但这样会导致打包后文件非常大!
- 会影响全局环境。
3. 3. useBuiltIns: 'usage'

与 entry 相比,会按需加载需要的语法转换模块,但是同样还是会影响全局环境
因此:一般在项目里使用这样方式
4. 4. npm 包怎么办?
如果直接导入 @babel/polyfill 及其提供的内置函数,如 Promise 、 Set 和 Map ,这些都会污染全局范围。
虽然这对于应用或命令行工具来说可能是可以的,但如果您的代码是打算发布供其他人使用的库,或者您无法完全控制代码的运行环境,则会成为一个问题。
因此需要一个沙盒环境,来和外部环境做隔离
5. 5. @babel/plugin-transform-runtime

语法转换的时候都是用的局部函数来实现的,而不是像 polyfill 直接引入重写原型链上的方法
更加适用于 npm 包的开发
6. 6. 各个插件的作用描述
上面都是从问题出发,说明用什么插件能解决问题,这里就总结描述下上面用到的各个插件的作用。
preset 或者 plugin
- @babel/preset-env
- @babel/plugin-transform-runtime
被依赖的具体实现
- @babel/polyfill
- @babel/runtime
6.1 @babel/preset-env
包含了每年新增的 ECMAScript 标准的转换插件,就等于以前使用的 babel-preset-es2015 + babel-preset-es2016 + babel-preset-es2017 + ...。
这个配置里的 corejs,其实就是声明 polyfill 的实现版本。
6.2 @babel/polyfill
Babel 默认无法转换的 内置函数 等的具体实现。
和 preset-env 中的 corejs 声明对应版本关系如下:
| preset-env 中的 corejs | 依赖的包,也就是入口需要引入的包,需要单独安 装 |
|---|---|
| 2 | @babel/polyfill |
| 3 | core-js |
6.3 @babel/plugin-transform-runtime
运行时实现 内置函数 等语法转换的插件,
这个配置里的 corejs,其实和 @babel/preset-env 一样,也是在声明具体的实现版本。但要注意,这里在实现上依赖的不是 @babel/polyfill, 而是 @babel/runtime
作用
- 默认情况下,
@babel/runtime需要添加到它的每个文件中。这种重复有时是不必要的,尤其是当您的应用程序分布在多个文件中时。@babel/plugin-transform-runtime帮助程序都将引用模块@babel/runtime,以避免编译输出重复。运行时将编译到您的构建中。 - 为代码创建沙盒环境,不会影响全局环境
6.4 @babel/runtime
| plugin-transform-runtime 中的 corejs | 依赖的包,需要单独安装 |
|---|---|
| false | @babel/runtime |
| 2 | @babel/runtime-corejs2 |
| 3 | @babel/runtime-corejs3 |
请注意,不是每个版本都能实现所有语法的转换
corejs: 2仅支持全局变量(例如 Promise ) 和静态属性(例如 Array.from ),corejs: 3还支持实例属性(例 如[].includes).
6.5 core-js
这个其实就是 ECMAScript 中新标准中的 新的内置函数、静态方法、实例方法 等等语法的具体实现。
只是根据实现场景,分为了两类
- 全局实现,
core-js - 运行时实现,
@babel/runtime-corejs